/**
 * Dans.com Inc. Copyright (c) 2011-2020 All Rights Reserved
 */
package com.example.mqreceiver;


import event.BusinessEvent;
import org.apache.commons.lang3.StringUtils;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @author ke
 * <p>
 * Created by on 2020-10-24 14:46
 */
public abstract class AbstractMQEventProcessor implements MqEventProcessor {


//        @Autowired
//        private EventHistoryService eventHistoryService;

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void action(BusinessEvent event) {
        if (null == event) {
            return;
        }

        /**
         * 判断事件是否满足条件
         */
        if (!condition(event)) {
            return;
        }

        setEventIdentifier(event);

        Integer influencing = recordEvent(event);
        if (null != influencing && influencing == 1) {
            processEvent(event);
        } else {
//            log.info("duplicate event:{} will be ignore", event);
        }
    }

    /**
     * 记录事件，包括幂等性控制
     *
     * @param event
     * @return 当返回0时，则重复插入
     */
    protected Integer recordEvent(BusinessEvent event) {
        // TODO: 2021/5/21 此处用于幂等性验证
        return 1;
        //        return eventHistoryService
        //                .saveEvent(event.getUserId(), event.getUserType().getType(), event.getEventId(),
        //                        event.getEventIdentifier(), JsonUtil.toJSON(event));
    }

    /**
     * 执行事件
     *
     * @param event
     * @return void
     * @author kehong
     * @date 2021-05-26
     */
    protected abstract void processEvent(BusinessEvent event);

    /**
     * 设置事件标志
     *
     * @param event
     */
    protected abstract void setEventIdentifier(BusinessEvent event);

    private static final String EVENT_SEPARATOR = "_";

    private static final String EVENT_IDENTIFIER_PREFIX = "event";

    protected String getEventIdentifier(String eventId, String businessId, String... others) {
        List<String> elements = new ArrayList<>();
        elements.add(EVENT_IDENTIFIER_PREFIX);
        elements.add(eventId);
        elements.add(businessId);

        if (null != others && others.length > 0) {
            for (String o : others) {
                if (StringUtils.isNotEmpty(o)) {
                    elements.add(o);
                }
            }
        }

        return StringUtils.join(elements, EVENT_SEPARATOR);
    }

}
